package ua.pp.bizon.yandex.uploader.atom;

import ua.pp.bizon.yandex.api.IHTTPUtils;
import ua.pp.bizon.yandex.api.IUserDataManager;
import ua.pp.bizon.yandex.api.ObjectLookup;

import java.io.StringReader;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;

import org.apache.abdera.model.Document;
import org.apache.abdera.model.Element;
import org.apache.abdera.parser.stax.FOMParserFactory;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.http.HttpException;
import org.apache.http.client.HttpResponseException;

public class AlbumsListFactory {

	private static final Log LOG = LogFactory.getLog(AlbumsListFactory.class);

	protected static AlbumsList get(AppLink appLink) {
		AlbumsList albumsList = null;
		do {
			try {
				albumsList = read(appLink);
			} catch (HttpException e) {
				LOG.warn("error during getting service document, retry", e);
			}
		} while (albumsList == null);
		return albumsList;
	}

	protected static AlbumsList read(AppLink appLink) throws HttpException {
		LOG.debug("getting service document for albums");
		String url = appLink.getLink();
		AlbumsList albumsList = new AlbumsList(null, "", new LinkedList<EntryAlbum>());
		String res = null;
		try {
			res = ObjectLookup.lookup(IHTTPUtils.class).get(url, ObjectLookup.lookup(IUserDataManager.class).get().getToken());
		} catch (HttpResponseException e) {
			throw new HttpException(e.getMessage(), e);
		}
		LOG.debug("service document for albums has being got");
		Document<Element> document = new FOMParserFactory().getParser().parse(new StringReader(res));
		// System.out.println(document.getRoot());
		List<Element> tokens = document.getRoot().getElements();
		Map<String, List<EntryAlbum>> notAdded = new HashMap<String, List<EntryAlbum>>();
		for (Element e : tokens) {
			if (e.getQName().getLocalPart().equals("author")) {
				albumsList.setAutorName(e.getElements().get(0).getText());
			} else if (e.getQName().getLocalPart().equals("entry")) {
				EntryAlbum album = new EntryAlbum(e);
				String link = album.getLink(EntryAlbum.SELF).getLink();
				if (notAdded.containsKey(link)) {
					for (EntryAlbum a : notAdded.get(link)) {
						album.addAlbum(a);
					}
					notAdded.remove(link);
				}
				if (album.getLink(EntryAlbum.PARENT) != null) {
					String parentLink = album.getLink(EntryAlbum.PARENT).getLink();
					EntryAlbum parent = albumsList.getAlbumByLink(parentLink);
					if (parent != null) {
						parent.addAlbum(album);
					} else {
						if (!notAdded.containsKey(parentLink)) {
							notAdded.put(parentLink, new LinkedList<EntryAlbum>());
						}
						notAdded.get(parentLink).add(album);
					}
				} else {
					albumsList.addAlbum(album);
				}
			}
		}
		if (!notAdded.isEmpty()) {
			LOG.warn("not added: " + notAdded.toString());
		}
		LOG.debug("service document for albums has being parsed");
		return albumsList;
	}

}
